home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Arsenal Files 4
/
The Arsenal Files 4 (Arsenal Computer).ISO
/
casm
/
au116-as.exe
/
UTIL
/
GFORMAT.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-19
|
12KB
|
416 lines
#include "..\au.hpp"
/***************************************************************/
#define LAST_BYTE 20600 /* For speed purposed, don't check beyond this point */
struct CHECK
{
int search_pos;
char *match;
int start_pos;
char is_self;
ARC_TYPE type;
int version; // Version code to at least start with
} check[] =
{
0, "PK\003", 0, 0, ZIP, 4, /* Pkzip */
0, "`Ω", 0, 0, ARJ, 8, /* ARJ */
0, "\x1A\x14\x00", 0, 0, ARC7,52, /* ARC 7.x */
0, "HLSQZ1", 0, 0, SQZ, 63, /* SQZ 1.08 */
0, "\x1aHP%", 0, 0, HYP, 73, /* Hyper 2.5 */
0, "\x1aST%", 0, 0, HYP, 73, /* Hyper 2.5 */
0, "HPAK", 0, 0, HPK, 75, /* Hpack 0.75c */
0, "\x91" "3HF", 0, 0, HAP, 76, /* HAP 3.0 */
0, "MDmd", 0, 0, MD, 77, /* MD 1.0 */
0, "RE~^", 0, 0, RAR, 78, /* RAR 1.40 */
0, "Rar!\x1a", 0, 0, RAR, 81, /* RAR 1.50 */
0, "UC2", 0, 0, UC2, 80, /* UC2 */
0, "GIF87", 0, 0, GIF87, 83, /* GIF87a */
0, "GIF89", 0, 0, GIF89, 84, /* GIF89a */
2, "-lh", 0, 0, LZH, 2, /* LHA 1.x/2.x */
2, "-lz", 0, 0, LZS, 1, /* Larc 3.33 */
20, "\xDC\xA7\xC4\xFD", 0, 0, ZOO, 10, /* Zoo */
1262, "-lh", 1260, 1, LZH, 19, /* LHARC .COM 1.12 file */
1265, "-lh", 1263, 1, LZH, 14, /* LHARC .COM 1.13 file */
1292, "-lh", 1290, 1, LZH, 12, /* LHARC .COM 1.0 */
1294, "-lh", 1292, 1, LZH, 21, /* LHARC .EXE 1.12S */
1297, "-lh", 1295, 1, LZH, 16, /* LHARC .EXE 1.13S */
1324, "-lh", 1322, 1, LZH, 13, /* LHARC .EXE 1.0 */
1637, "-lh", 1635, 1, LZH, 17, /* LHARC .EXE 2.05 */
1638, "-lh", 1636, 1, LZH, 18, /* LHARC .EXE 2.06 */
1872, "-lh", 1870, 1, LZH, 15, /* LHARC .EXE 1.13L */
1873, "-lh", 1871, 1, LZH, 20, /* LHARC .EXE 1.12L */
1947, "-lh", 1945, 1, LZH, 18, /* LHARC .EXE 2.06 (with paths) */
2492, "ZOO", 2535, 1, ZOO, 59, /* Sez (Zoo) 2.30 */
4694, "NoGate", 6674, 1, PAK, 25, /* PAK .EXE 1.5x */
4764, "NoGate", 6744, 1, PAK, 26, /* PAK .EXE 1.6x */
4887, "NoGate", 6867, 1, PAK, 28, /* PAK .EXE 2.5x */
5313, "`Ω", 5313, 1, ARJ, 55, /* ARJ .EXE 2.30B JR */
5329, "`Ω", 5329, 1, ARJ, 58, /* ARJ .EXE 2.30 JR */
5345, "`Ω", 5345, 1, ARJ, 39, /* ARJ .EXE 2.10 JR */
5377, "`Ω", 5377, 1, ARJ, 41, /* ARJ .EXE 2.20 JR */
5393, "`Ω", 5393, 1, ARJ, 56, /* ARJ .EXE 2.22 JR */
5473, "`Ω", 5473, 1, ARJ, 68, /* ARJ .EXE 2.39A JR */
5763, "`Ω", 5763, 1, ARJ, 70, /* ARJ .EXE 2.39F JR */
5779, "`Ω", 5779, 1, ARJ, 72, /* ARJ .EXE 2.41 JR */
5947, "`Ω", 5947, 1, ARJ, 33, /* ARJ .EXE 1.0 JR */
6159, "`Ω", 6159, 1, ARJ, 35, /* ARJ .EXE 1.10 JR */
6160, "`Ω", 6160, 1, ARJ, 37, /* ARJ .EXE 2.00 JR */
6491, "RE~^", 6491, 1, RAR, 79, /* RAR .EXE 1.40 SFX */
6679, "NoGate", 8601, 1, PAK, 27, /* PAK .EXE 2.0x - 2.1x */
6834, "Buerg", 7746, 1, ARC, 42, /* ARC .EXE 6.00 */
6836, "Buerg", 7716, 1, ARC, 43, /* ARC .EXE 6.02 */
8929, "PKWARE", 9758, 1, ARC, 29, /* PKARC .EXE 3.5 */
9774, "PKWARE", 13138, 1, ARC, 31, /* PKARC .EXE 3.61 */
9790, "PKWARE", 13160, 1, ARC, 30, /* PKARC .EXE 3.6 */
12784, "PK\003", 12784, 1, ZIP, 24, /* PKZIP .EXE 1.10 */
13989, "`Ω", 13989, 1, ARJ, 32, /* ARJ .EXE 1.00 */
14039, "`Ω", 14039, 1, ARJ, 34, /* ARJ .EXE 1.10 */
14060, "`Ω", 14060, 1, ARJ, 36, /* ARJ .EXE 2.00 */
14666, "`Ω", 14666, 1, ARJ, 38, /* ARJ .EXE 2.10 */
14778, "`Ω", 14778, 1, ARJ, 40, /* ARJ .EXE 2.20 */
14810, "`Ω", 14810, 1, ARJ, 54, /* ARJ .EXE 2.30B */
14858, "`Ω", 14858, 1, ARJ, 57, /* ARJ .EXE 2.30 */
15104, "`Ω", 15104, 1, ARJ, 67, /* ARJ .EXE 2.39A */
15106, "`Ω", 15106, 1, ARJ, 71, /* ARJ .EXE 2.41 */
15122, "`Ω", 15122, 1, ARJ, 69, /* ARJ .EXE 2.39F */
15198, "PK\003", 15198, 1, ZIP, 22, /* PKZIP .EXE 0.92 */
15512, "PK\003", 15512, 1, ZIP, 23, /* PKZIP .EXE 1.02 */
15563, "PK\003", 15563, 1, ZIP, 64, /* PKZIP .EXE 2.00 */
15770, "PK\003", 15770, 1, ZIP, 64, /* PKZIP .EXE 2.04g */
};
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
void ARC_HANDLE::set_trailer_pos(AU *au)
{
ARC_RECORD record;
long save_pos;
int retCode;
trailer_pos = -1; /* No trailer by default */
save_pos = pos;
while ((retCode = get_record(au, &record)) >= 0)
{
if (retCode == -2)
goto Error0;
}
if (read_char() == 254)
trailer_pos = seek(0, SEEK_CUR); // seek will need to be smarter
Error0:
pos = save_pos;
isFirst = TRUE;
rec_number = 0;
return;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static char pos_check(char *buffer, int num_chars, int pos, char *search)
{
int len;
len = strlen(search);
if (num_chars < pos+len)
return FALSE;
if (memcmp(search, buffer+pos, len) == 0)
return TRUE;
else
return FALSE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
static BOOLEAN ValidArjHeader(char *buffer, unsigned int pos)
{
unsigned int size;
unsigned long crc1, crc2;
unsigned int j;
unsigned char c1,c2,c3,c4;
size = (buffer[pos+3] << 8) + buffer[pos+2];
if (size <= 2600)
{
crc1 = crc32_string(buffer+pos+4, size);
j = pos+4+size;
c1 = buffer[j];
c2 = buffer[j+1];
c3 = buffer[j+2];
c4 = buffer[j+3];
crc2 = (unsigned long)c1 |
((unsigned long)c2 << 8) |
((unsigned long)c3 << 16) |
((unsigned long)c4 << 24);
if (crc1 == crc2)
{
return TRUE;
}
}
return FALSE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
BOOLEAN ARC_HANDLE::search_arj(char *file_name, int num_chars, long start,
long end, char *buffer)
{
unsigned int c;
unsigned int i;
if (num_chars > start)
{
c = end;
if (c > num_chars)
c = num_chars;
c--;
for (i = start; i < c; i++)
{
if (buffer[i] == '\x60' && buffer[i+1] == '\xEA')
{
if (ValidArjHeader(buffer, i))
{
pos = i;
isFirst = FALSE;
type = ARJ;
if (strstr(file_name, ".EXE") != NULL ||
strstr(file_name, ".COM") != NULL)
{
is_self = TRUE;
}
else
is_self = FALSE;
return TRUE;
}
}
}
}
return FALSE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
/* .HA files are hard to identify. This function takes a stab at reducing */
/* the possibility of falsely identifying a file */
BOOLEAN ARC_HANDLE::search_ha(int num_chars, char *buffer)
{
unsigned int i;
unsigned int num_to_check;
/* .HA files start with HA. Easy enough to check for */
if (buffer[0] != 'H' || buffer[1] != 'A')
return FALSE;
/* HA files are at least 34 bytes long */
if (num_chars < 34)
return FALSE;
/* HA files almost certainly have some data that can be recoginized
as binary inside them */
num_to_check = num_chars > 200 ? num_chars : 200;
for (i=2; i < num_to_check; i++)
{
if (!is_binary_file_char(buffer[i]))
{
pos = i;
is_self = FALSE;
isFirst = TRUE;
type = HA;
version = 74;
return TRUE;
}
}
return FALSE;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
long ARC_HANDLE::find_last_non_zero()
{
char buffer[129];
int buf_size;
int i;
seek(-128L, SEEK_END); /* 128 from the end */
buf_size = read(buffer, 128);
for (i = buf_size-1; i >= 0; i--)
{
if (buffer[i] != '\0')
break;
}
return file_length() - buf_size + i;
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
STATUS ARC_HANDLE::get_format(AU *au, char *file_name)
{
int c,d,e;
int num_chars;
int i;
char *buffer;
long find_pos;
buffer = (char *)au_malloc(au, LAST_BYTE);
seek(0, SEEK_SET);
num_chars = read_raw(buffer, LAST_BYTE);
is_self = FALSE;
version = 0; /* Unknown version */
pos = 0;
for (i=0; i<sizeof(check)/sizeof(struct CHECK); i++)
{
if (pos_check(buffer, num_chars, check[i].search_pos, check[i].match))
{
if (check[i].is_self)
{
if (!au->self_extracts)
break;
if (strstr(file_name, ".COM") == NULL &&
strstr(file_name, ".EXE") == NULL)
{
break;
}
}
/* Additional check on arj to make sure it isn't a false
recognition */
if (check[i].type == ARJ)
{
if (!ValidArjHeader(buffer, (long)check[i].start_pos))
break;
}
pos = (long)check[i].start_pos;
version = check[i].version;
is_self = check[i].is_self;
type = check[i].type;
goto Error0;
}
}
/* Arj is pretty flakey about changing every darn version. their lite
self extractors seem to work in the 5000 to 6500 range, the regular
from 13500 to 18000 */
if (search_arj(file_name, num_chars, 0, 4999, buffer))
{
version = 8;
goto Error0;
}
if (search_arj(file_name, num_chars, 5000, 6500, buffer))
{
version = 65;
goto Error0;
}
if (search_arj(file_name, num_chars, 6501, 13499, buffer))
{
version = 1;
goto Error0;
}
if (search_arj(file_name, num_chars, 13500, 18000, buffer))
{
version = 66;
goto Error0;
}
/* Try for HA */
if (search_ha(num_chars, buffer))
{
goto Error0;
}
/* Try for ARC/PAK *************************/
seek(0, SEEK_SET);
c = read_char();
d = read_char();
if (c == 26 && d > 0 && d < 12)
{
find_pos = find_last_non_zero();
seek(find_pos, SEEK_SET);
c = read_char();
if (c == 26)
{
version = 47;
type = ARC;
}
else
{
version = 48;
type = PAK;
}
goto Error0;
}
/* Try for LBR */
if (c == 0x00 && d == 0x20)
{
if (read_char() == 0x20)
{
seek(10, SEEK_SET);
c = read_char();
d = read_char();
e = read_char();
if (c==0x20 && d==0x20 && e==0x00)
{
version = 61;
type = LBR;
goto Error0;
}
}
}
/* Try for DWC */
find_pos = find_last_non_zero();
seek(find_pos-2, SEEK_SET);
c = read_char();
d = read_char();
e = read_char();
if (c=='D' && d=='W' && e=='C')
{
version = 11;
type = DWC;
goto Error0;
}
type = NONARC; /* Not an archive */
Error0:
free(buffer);
/* Set the trailer information pointer if .PAK */
if (type == PAK && au->unarc_paths == ON)
{
set_trailer_pos(au);
type = PAK;
}
else if (type == ARC)
{
set_trailer_pos(au);
if (trailer_pos == -1)
type = ARC;
else
{
if (au->unarc_paths != ON)
trailer_pos = -1;
version = 48;
type = PAK;
}
}
return SUCCESS;
}